﻿#region Using Directives

    using System;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;

    using Csla;
    using Csla.Data;
    using Csla.Server;
    using Csla.Reflection;

    using MarketPulse.BusinessLogic.Core;
    using MarketPulse.DataAccess;
    using MarketPulse.Reporting.Core;
    using MarketPulse.Reporting.Core.Criteria;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Factory class for producing ReportingAnswerInfoLists
    /// </summary>
    public class ReportingAnswerFactory : ObjectFactory
    {
        #region Methods

        #region FetchMethods

        #region ReportingAnswerInfoList

        /// <summary>
        /// A factory class for producing ReportingAnswerInfoLists
        /// </summary>
        /// <param name="criteria">The client GUID and question GUID</param>
        /// <returns>The populated ReportingAnswerInfoList </returns>
        public ReportingAnswerInfoList FetchInfoList(ClientGUIDAndQuestionIDCriteria criteria)
        {
            try
            {
                using (var manager = ContextManager<DataContextObjects.Reporting.MUMReporting_dev>.GetManager(Database.ReportingSystem))
                {
                    // Create an empty instance of ReportingAnswerInfoList to be returned.
                    var reportingAnswerInfoList = (ReportingAnswerInfoList)MethodCaller.CreateInstance(typeof(ReportingAnswerInfoList));

                    // Mark the new instance of ReportingAnswerInfoList as writable as it inherits from MarketPulseReadOnlyBase
                    SetIsReadOnly(reportingAnswerInfoList, false);

                    // Select the resultset from the database.
                    var reportingAnswerInfoSelect = manager.DataContext.UspReportingAnswerSelectByClientGUIDAndQuestionID(criteria.ClientGUID, criteria.QuestionID);

                    // Iterate over each row and append the object to the ReportingAnswerInfoList
                    foreach (var result in reportingAnswerInfoSelect)
                    {
                        // Create an empty instance of ReportingAnswerInfo to be appended to the ReportingAnswerInfoList
                        var reportingAnswerInfo = (ReportingAnswerInfo)MethodCaller.CreateInstance(typeof(ReportingAnswerInfo));

                        // Load the base properties
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.GUIDProperty, result.AnswerGUID.Value);

                        // TODO: What do we do about these properties on a Reporting object?
                        /*
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.ObsoleteProperty, result.Obsolete.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                        */

                        // Load the ReportingAnswerInfo specific properties
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.AnswerIDProperty, result.AnswerID.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.VisitGUIDProperty, result.VisitGUID.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.ParentAnswerGUIDProperty, result.ParentAnswerGUID);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.QuestionGUIDProperty, result.QuestionGUID.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.TypeProperty, result.AnswerType);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.DisplayNumberProperty, result.DisplayNumber);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.AnswerNumberProperty, result.AnswerNumber);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.AnswerTextProperty, result.AnswerText);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.AnswerScoreProperty, result.AnswerScore.Value);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.AnswerValueProperty, result.AnswerValue);
                        LoadProperty(reportingAnswerInfo, ReportingAnswerInfo.TransferDateTimeProperty, result.TransferDateTime);

                        // Mark the ReportingAnswerInfo object as old so CSLA knows it has changed
                        MarkOld(reportingAnswerInfo);

                        // Add the ReportingAnswerInfo object to the ReportingAnswerInfoList collection
                        reportingAnswerInfoList.Add(reportingAnswerInfo);
                    }

                    // Mark the new instance of ReportingAnswerInfoList as read-only before returning it to the client
                    SetIsReadOnly(reportingAnswerInfoList, true);

                    // Mark the ReportingAnswerInfoList object as old so CSLA knows it has changed
                    MarkOld(reportingAnswerInfoList);

                    // Return the newly populated ReportingAnswerInfoList
                    return reportingAnswerInfoList;
                }
            }
            catch (InvalidOperationException ioe)
            {
                //TODO log exception appropriately before re throwing
                throw ioe;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #endregion

        #endregion

    }
}
